package com.demo.order.controller;

import com.demo.order.feign.ProductFeignClient;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.Map;

/**
 * 熔断器测试控制器
 * 提供熔断器功能测试接口
 */
@Slf4j
@RestController
@RequestMapping("/api/test")
public class CircuitBreakerTestController {

    @Autowired
    private ProductFeignClient productFeignClient;

    /**
     * 测试商品服务调用
     * @param productId 商品ID
     * @return 调用结果
     */
    @PostMapping("/product/reduce-stock/{productId}")
    public Map<String, Object> testReduceStock(@PathVariable Long productId, 
                                              @RequestParam(defaultValue = "1") Integer quantity) {
        log.info("测试扣减库存: productId={}, quantity={}", productId, quantity);
        
        try {
            Map<String, Object> result = productFeignClient.reduceStock(productId, quantity);
            log.info("扣减库存结果: {}", result);
            return result;
        } catch (Exception e) {
            log.error("扣减库存异常: ", e);
            Map<String, Object> errorResult = new HashMap<>();
            errorResult.put("success", false);
            errorResult.put("message", "调用异常: " + e.getMessage());
            return errorResult;
        }
    }

    /**
     * 测试获取商品信息
     * @param productId 商品ID
     * @return 商品信息
     */
    @GetMapping("/product/info/{productId}")
    public Map<String, Object> testGetProductInfo(@PathVariable Long productId) {
        log.info("测试获取商品信息: productId={}", productId);
        
        try {
            Map<String, Object> result = productFeignClient.getProductInfo(productId);
            log.info("获取商品信息结果: {}", result);
            return result;
        } catch (Exception e) {
            log.error("获取商品信息异常: ", e);
            Map<String, Object> errorResult = new HashMap<>();
            errorResult.put("success", false);
            errorResult.put("message", "调用异常: " + e.getMessage());
            return errorResult;
        }
    }

    /**
     * 批量测试接口，用于触发熔断器
     * @param productId 商品ID
     * @param count 调用次数
     * @param delay 调用间隔（毫秒）
     * @return 测试结果统计
     */
    @PostMapping("/product/batch-test/{productId}")
    public Map<String, Object> batchTest(@PathVariable Long productId,
                                        @RequestParam(defaultValue = "20") Integer count,
                                        @RequestParam(defaultValue = "100") Long delay) {
        log.info("开始批量测试: productId={}, count={}, delay={}ms", productId, count, delay);
        
        Map<String, Object> statistics = new HashMap<>();
        int successCount = 0;
        int failureCount = 0;
        int fallbackCount = 0;
        
        for (int i = 1; i <= count; i++) {
            try {
                Map<String, Object> result = productFeignClient.reduceStock(productId, 1);
                Boolean success = (Boolean) result.get("success");
                Boolean isFallback = result.containsKey("error") && 
                    result.get("error").toString().contains("CircuitBreaker triggered");
                
                if (isFallback) {
                    fallbackCount++;
                    log.warn("第{}次调用触发降级", i);
                } else if (Boolean.TRUE.equals(success)) {
                    successCount++;
                    log.info("第{}次调用成功", i);
                } else {
                    failureCount++;
                    log.warn("第{}次调用失败: {}", i, result.get("message"));
                }
                
                // 延迟
                if (delay > 0) {
                    Thread.sleep(delay);
                }
                
            } catch (Exception e) {
                failureCount++;
                log.error("第{}次调用异常: ", i, e);
            }
        }
        
        statistics.put("totalCalls", count);
        statistics.put("successCount", successCount);
        statistics.put("failureCount", failureCount);
        statistics.put("fallbackCount", fallbackCount);
        statistics.put("successRate", (double) successCount / count * 100);
        statistics.put("failureRate", (double) failureCount / count * 100);
        statistics.put("fallbackRate", (double) fallbackCount / count * 100);
        
        log.info("批量测试完成: {}", statistics);
        return statistics;
    }
}